import { fileURLToPath, URL } from 'node:url';
import commonjsExternals from 'vite-plugin-commonjs-externals';
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import fs from 'fs';
// https://vitejs.dev/config/
type MaybeType<T extends {}> = {
  [key in keyof T]: unknown;
};
const isObject = <T extends {} = {},>(v: unknown): v is MaybeType<T> => {
  return typeof v === 'object' && v !== null;
};
interface TSConfigCompilerOptions {
  types: string[];
}
interface TSConfig {
  compilerOptions: TSConfigCompilerOptions;
}
const isString = (v: unknown): v is string => typeof v === 'string';
const isTypedArray = <T,>(v: unknown, isTyped: (element: unknown) => element is T): v is string => {
  return Array.isArray(v) && v.every(element => isTyped(element));
};
const isTSConfigCompilerOptions = (v: unknown): v is TSConfigCompilerOptions => {
  return isObject<TSConfigCompilerOptions>(v) && isTypedArray(v.types, isString);
};
const isTSConfig = (v: unknown): v is TSConfig => {
  return isObject<TSConfig>(v) && isTSConfigCompilerOptions(v.compilerOptions);
};
const getExternals = (): string[] => {
  try {
    const json = JSON.parse(fs.readFileSync('./tsconfig.json').toString()) as unknown;
    if (isTSConfig(json)) {
      return json.compilerOptions.types.map(v => v.replace('node/', ''));
    }
  } catch (e) {
    console.log(e instanceof Error ? e.message : e);
  }
  return [];
};
const externals = getExternals();
export default defineConfig({
  plugins: [
    commonjsExternals({ externals }),
    vue(),
  ],
  base: '',
  build: {
    outDir: 'dist/src',
  },
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
});
